package com.zbkj.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.constants.CommunityConstants;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.constants.TogetherConstants;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.community.CommunityNotes;
import com.zbkj.common.model.community.CommunityReply;
import com.zbkj.common.model.community.CommunityReplyLike;
import com.zbkj.common.model.together.TogetherReply;
import com.zbkj.common.model.together.TogetherReplyLike;
import com.zbkj.common.model.together.UserTogether;
import com.zbkj.common.model.user.User;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.CommunityReplyAddRequest;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.TogetherReplyRequest;
import com.zbkj.common.response.CommunityCommentReplyResponse;
import com.zbkj.common.response.TogetherReplyResponse;
import com.zbkj.common.response.TogetherReplyResponse;
import com.zbkj.common.result.CommonResultCode;
import com.zbkj.common.result.CommunityResultCode;
import com.zbkj.service.dao.TogetherReplyDao;
import com.zbkj.service.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class TogetherReplyServiceImpl extends ServiceImpl<TogetherReplyDao, TogetherReply> implements TogetherReplyService {

    @Resource
    TogetherReplyDao dao;

    @Autowired
    UserService userService;

    @Autowired
    UserTogetherService userTogetherService;

    @Autowired
    TogetherReplyLikeService togetherReplyLikeService;

    @Autowired
    private AsyncService asyncService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    public void likeReply(Integer replyId) {
        Integer userId = userService.getUserIdException();
        likeReply1(replyId, userId);
    }

    public void likeReply1(Integer replyId, Integer userId) {
        TogetherReply reply = getById(replyId);
//        if (!reply.getAuditStatus().equals(CommunityConstants.COMMUNITY_REPLY_AUDIT_SUCCESS)) {
//            throw new CrmebException(CommunityResultCode.COMMUNITY_REPLY_AUDIT_STATUS_EXCEPTION);
//        }
        TogetherReplyLike replyLike = togetherReplyLikeService.getDetail(replyId, userId);
        if (ObjectUtil.isNotNull(replyLike)) {
            boolean remove = togetherReplyLikeService.removeById(replyLike.getId());
            if (!remove) {
                throw new CrmebException(CommonResultCode.ERROR.setMessage("评论取消点赞失败"));
            }
//            asyncService.communityReplyLikeOrClean(replyId, Constants.OPERATION_TYPE_SUBTRACT);
            return;
        }
        replyLike = new TogetherReplyLike();
        replyLike.setTogetherId(reply.getTogetherId());
        replyLike.setReplyId(reply.getId());
        replyLike.setUid(userId);

//
//        transactionTemplate.execute(e->{
//
//
//        })
        boolean save = togetherReplyLikeService.save(replyLike);
        if (!save) {
            throw new CrmebException(CommonResultCode.ERROR.setMessage("评论点赞失败"));
        }
        asyncService.togetherReplyLikeOrClean(replyId, Constants.OPERATION_TYPE_ADD);
    }

    @Override
    public PageInfo<TogetherReplyResponse> findNoteReplyPageList(Integer togetherId, PageParamRequest request) {
        PageInfo<TogetherReplyResponse> pageInfo = findNotePageList(togetherId, request);
        List<TogetherReplyResponse> list = pageInfo.getList();
        if (CollUtil.isEmpty(list)) {
            return pageInfo;
        }
        Integer userId = userService.getUserId();
        if (userId <= 0) {
            return pageInfo;
        }
        List<TogetherReplyLike> replyLikeList = togetherReplyLikeService.findListByNoteIdAndUid(togetherId, userId);
        if (CollUtil.isEmpty(replyLikeList)) {
            return pageInfo;
        }
        List<Integer> likeList = replyLikeList.stream().map(TogetherReplyLike::getReplyId).collect(Collectors.toList());
        for (TogetherReplyResponse response : list) {
            if (likeList.contains(response.getId())) {
                response.setIsLike(true);
            }
            if (CollUtil.isEmpty(response.getReplyList())) {
                continue;
            }
            response.getReplyList().forEach(e -> {
                if (likeList.contains(e.getId())) {
                    e.setIsLike(true);
                }
            });
        }
        return pageInfo;
    }
    private List<TogetherReply> findReplyByParentId(Integer replyId) {
        LambdaQueryWrapper<TogetherReply> lqw = Wrappers.lambdaQuery();
        lqw.eq(TogetherReply::getParentId, replyId);
        lqw.eq(TogetherReply::getType, CommunityConstants.COMMUNITY_REPLY_TYPE_REPLY);
//        lqw.eq(TogetherReply::getAuditStatus, CommunityConstants.COMMUNITY_REPLY_AUDIT_SUCCESS);
        lqw.eq(TogetherReply::getIsDel, Constants.COMMON_IS_FILED_ZERO);
        lqw.orderByDesc(TogetherReply::getId);
        return dao.selectList(lqw);
    }
//    @Override
    public PageInfo<TogetherReplyResponse> findNotePageList(Integer noteId, PageParamRequest pageRequest) {
        Page<TogetherReply> page = PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());
        LambdaQueryWrapper<TogetherReply> lqw = Wrappers.lambdaQuery();
        lqw.eq(TogetherReply::getTogetherId, noteId);
        lqw.eq(TogetherReply::getType, CommunityConstants.COMMUNITY_REPLY_TYPE_COMMENT);
//        lqw.eq(TogetherReply::getAuditStatus, CommunityConstants.COMMUNITY_REPLY_AUDIT_SUCCESS);
        lqw.eq(TogetherReply::getIsDel, Constants.COMMON_IS_FILED_ZERO);
        lqw.orderByDesc(TogetherReply::getId);
        List<TogetherReply> list = dao.selectList(lqw);
        if (CollUtil.isEmpty(list)) {
            return CommonPage.copyPageInfo(page, new ArrayList<>());
        }


        List<TogetherReplyResponse> responseList = list.stream().map(r -> {
            TogetherReplyResponse replyResponse = new TogetherReplyResponse();
            BeanUtils.copyProperties(r, replyResponse);
            replyResponse.setAuditStatus(null);
            List<TogetherReply> replyList = findReplyByParentId(r.getId());
            if (CollUtil.isNotEmpty(replyList)) {
                List<TogetherReplyResponse> childReplyList = replyList.stream().map(reply -> {
                    TogetherReplyResponse childReply = new TogetherReplyResponse();
                    BeanUtils.copyProperties(reply, childReply);
                    return childReply;
                }).collect(Collectors.toList());
                replyResponse.setReplyList(childReplyList);
            }
            return replyResponse;
        }).collect(Collectors.toList());
        responseSetUserName(responseList);
        return CommonPage.copyPageInfo(page, responseList);
    }

    private void responseSetUserName(List<TogetherReplyResponse> responseList) {
        List<Integer> uidList = new ArrayList<>();
        responseList.forEach(r -> {
            if (!uidList.contains(r.getUid())) {
                uidList.add(r.getUid());
            }
            if (CollUtil.isNotEmpty(r.getReplyList())) {
                r.getReplyList().forEach(rc -> {
                    if (!uidList.contains(rc.getUid())) {
                        uidList.add(rc.getUid());
                    }
                    if (rc.getReviewUid() > 0 && !uidList.contains(rc.getReviewUid())) {
                        uidList.add(rc.getReviewUid());
                    }
                });
            }
        });
        Map<Integer, User> userMap = userService.getUidMapList(uidList);
        responseList.forEach(r -> {
            r.setNickname(userMap.get(r.getUid()).getNickname());
            r.setAvatar(userMap.get(r.getUid()).getAvatar());
            if (CollUtil.isNotEmpty(r.getReplyList())) {
                r.getReplyList().forEach(rc -> {
                    rc.setNickname(userMap.get(rc.getUid()).getNickname());
                    rc.setAvatar(userMap.get(rc.getUid()).getAvatar());
                    if (rc.getReviewUid() > 0) {
                        rc.setReviewUserNickname(userMap.get(rc.getReviewUid()).getNickname());
                    }
                });
            }
        });
    }
    @Override
    public Integer deleteReply(Integer replyId) {
        Integer userId = userService.getUserIdException();
        TogetherReply reply = getById(replyId);
        if (ObjectUtil.isNull(reply) && reply.getIsDel().equals(Constants.COMMON_IS_FILED_ONE)) {
            throw new CrmebException(CommunityResultCode.COMMUNITY_REPLY_NOT_EXIST);
        }
        if (!userId.equals(reply.getUid())) {
            throw new CrmebException(CommonResultCode.FORBIDDEN.setMessage("不能操作非自己的资源"));
        }
        dao.deleteById(replyId);
        UserTogether userTogether = userTogetherService.getById(reply.getTogetherId());
        userTogether.setReplyNum(userTogether.getReplyNum()-1);
        userTogetherService.updateById(userTogether);
        return getCountByNid(reply.getTogetherId());
    }

    public Integer getCountByNid(Integer nid) {
        LambdaQueryWrapper<TogetherReply> lqw = Wrappers.lambdaQuery();
        lqw.eq(TogetherReply::getIsDel, Constants.COMMON_IS_FILED_ZERO);
//        lqw.eq(TogetherReply::getAuditStatus, CommunityConstants.COMMUNITY_REPLY_AUDIT_SUCCESS);
        lqw.eq(TogetherReply::getTogetherId, nid);
        return dao.selectCount(lqw);
    }

    @Override
    public TogetherReplyResponse add(TogetherReplyRequest request) {
        Integer userId = userService.getUserIdException();
//        String platReplySwitch = systemConfigService.getValueByKeyException(CommunityConstants.COMMUNITY_REPLY_SWITCH);
//        if (platReplySwitch.contains(Constants.COMMON_SWITCH_CLOSE)) {
//            throw new CrmebException(CommunityResultCode.COMMUNITY_REPLY_PLAT_CLOSE);
//        }
        UserTogether userTogether = userTogetherService.getById(request.getTogetherId());
//        if (!communityNotes.getReplyStatus().equals(CommunityConstants.COMMUNITY_NOTE_IS_REPLY_OPEN)) {
//            throw new CrmebException(CommunityResultCode.COMMUNITY_NOTE_REPLY_IS_NOT_OPEN);
//        }
        request.setUserId(userId);
        TogetherReplyResponse response = create(request);
        response.setNoteReplyNum(userTogether.getReplyNum());
//        if (response.getAuditStatus().equals(CommunityConstants.COMMUNITY_REPLY_AUDIT_SUCCESS)) {
        response.setNoteReplyNum(response.getNoteReplyNum() + 1);
//        }
        userTogether.setReplyNum(userTogether.getReplyNum()+1);
        userTogetherService.updateById(userTogether);
        return response;
    }

    private TogetherReplyResponse create(TogetherReplyRequest request){
        TogetherReply reply = new TogetherReply();
        reply.setType(1);
        reply.setUid(request.getUserId());
        reply.setContent(request.getContent());
        reply.setAuditStatus(1);
        reply.setParentId(0);
        reply.setTogetherId(request.getTogetherId());
        if (request.getReplyId() > 0) {
            reply.setType(2);
            TogetherReply tempReply = getById(request.getReplyId());
            if (tempReply.getType().equals(1)) {
                reply.setParentId(tempReply.getId());
                reply.setParentUid(tempReply.getUid());
            } else {
                reply.setParentId(tempReply.getParentId());
                reply.setParentUid(tempReply.getParentUid());
                reply.setReviewId(tempReply.getId());
                reply.setReviewUid(tempReply.getUid());
            }
        }
//        String replyAuditSwitch = systemConfigService.getValueByKeyException(CommunityConstants.COMMUNITY_REPLY_AUDIT_SWITCH);
//        if (replyAuditSwitch.equals(Constants.COMMON_SWITCH_OPEN)) {
//            reply.setAuditStatus(CommunityConstants.COMMUNITY_REPLY_AUDIT_AWAIT);
//        }
        boolean save = save(reply);
        if (!save) {
            throw new CrmebException(CommonResultCode.ERROR.setMessage("共创评论失败"));
        }
//        if (reply.getAuditStatus().equals(CommunityConstants.COMMUNITY_REPLY_AUDIT_SUCCESS)) {
//            asyncService.noteAddReplyAfter(reply.getTogetherId(), reply.getParentId(), reply.getId());
//        }
        TogetherReplyResponse response = new TogetherReplyResponse();
        BeanUtils.copyProperties(reply, response);
        User user = userService.getInfo();
        response.setNickname(user.getNickname());
        response.setAvatar(user.getAvatar());
        response.setCreateTime(DateUtil.date());
        if (ObjectUtil.isNotNull(reply.getReviewUid()) && reply.getReviewUid() > 0) {
            User reviewUser = userService.getById(reply.getReviewUid());
            response.setReviewUserNickname(reviewUser.getNickname());
            response.setCountStart(0);
            response.setCreateTime(DateUtil.date());
        }
        return response;
    }

}
